import json
import os
from typing import List, Dict

from .book import Book


class BookManager:
    """图书管理系统类"""

    books = []
    dirname = os.path.dirname(__file__)
    filename = os.path.join(dirname, 'book_list.json')

    def __init__(self):
        # 初始化从json文件获取所有书籍信息
        self._init_books()

    def _init_books(self):
        try:
            f = open(self.filename, encoding='utf-8')
            try:
                # 读取Json字符串并转换为Python数据类型(字典列表)
                book_list: List[Dict] = json.loads(f.read())
                for book_dict in book_list:
                    # 每本书籍的字典信息转换成Book类的实例对象
                    book = Book(**book_dict)
                    # 每本书的实例对象book添加到books列表里
                    self.books.append(book)
            except Exception as e:
                print(e)
            finally:
                f.close()
        except FileNotFoundError:
            pass

    def write2json(self):
        """保存并写入json文件"""
        info_list = [book.__dict__ for book in self.books]

        with open(self.filename, 'w', encoding='utf-8') as f:
            # Python数据类型转换为Json字符串
            json_str = json.dumps(info_list, indent=4, ensure_ascii=False)
            f.write(json_str)

    @staticmethod
    def print_info():
        """显示选择菜单"""
        print()
        print("=" * 15)
        print("1.查询所有书籍")
        print("2.添加书籍")
        print("3.借阅书籍")
        print("4.归还书籍")
        print("5.退出系统")
        print("=" * 15)

    def show_all_book(self):
        """查询所有书籍"""
        if not self.books:
            print('很抱歉，暂时没有一本书收录于系统内，请用您的爱心给予助力，谢谢~！')
            return

        for book in self.books:
            print(book)

    def check_book(self, name):
        """检查书籍是否存在和对应的借阅状态

        :param name: 书名
        :return:
            book: 书籍信息(dict)
                - 存在返回book实例对象
                - 不存在返回None
        """
        for book in self.books:
            if book.name == name:
                return book

        return None

    def add_book(self):
        """添加书籍"""
        name = input("请输入书籍名称：")
        book = self.check_book(name)
        if book:
            print('这本书已经收录入系统啦！')
            return

        author = input("请输入作者名称：")
        comment = input("请输入书籍推荐语：")

        # 创建实例对象book
        book = Book(name, author, comment)

        # 将实例对象book添加到列表books里
        self.books.append(book)
        print('书籍录入成功！\n')

    def lend_book(self):
        """借阅书籍"""
        name = input("请输入你想借阅书籍的名称：")
        book = self.check_book(name)
        if book and book.state == 0:
            print('借阅成功！借了不看会变胖噢～')
            # 借阅成功后，更新书的借阅状态
            book.state = 1  # 已借出
        elif book and book.state == 1:
            print('你来晚一步，这本书已经被借走了噢')
        else:
            print('这本书暂时没有收录在系统里呢')

    def return_book(self):
        """归还书籍"""
        name = input("请输入你要归还书籍的名称：")
        book = self.check_book(name)
        if book and book.state == 0:
            print('这本书没有被借走，在等待有缘人的垂青呢！')
        elif book and book.state == 1:
            print('归还成功！')
            # 归还成功后，更新书的借阅状态
            book.state = 0  # 未借出
        else:
            print('没有这本书噢，你恐怕输错了书名～')

    def run(self):
        """显示选择菜单，根据不同选项调用不同功能"""
        print(
            '欢迎使用流浪图书管理系统，每本沉默的好书都是一座流浪的岛屿，希望你有缘发现并着陆，为精神家园找到一片栖息地。')

        while True:
            self.print_info()

            try:
                choice = int(input("请输入数字选择对应的功能："))
            except ValueError:
                print('输入不合法，请输1~5之间的任意数字')
                continue

            if choice == 1:  # 查询所有书籍
                self.show_all_book()
            elif choice == 2:  # 添加书籍
                self.add_book()
            elif choice == 3:  # 借阅书籍
                self.lend_book()
            elif choice == 4:  # 归还书籍
                self.return_book()
            elif choice == 5:  # 退出系统
                print('\n感谢使用！愿你我成为爱书之人，在茫茫书海里相遇。')
                break
            else:
                print("输入不合法，请输1~5之间的任意数字")

        # 程序结束前将book_list保存并写入json文件
        self.write2json()
